home *** CD-ROM | disk | FTP | other *** search
Wrap
/* Circluar Layout Sample Program By Eric Mader, After Mike Fairman, Oliver Steele et. al. 1.0B2 (09/09/93, MD) -- now allocates its own graphics client of 1 MB instead of accepting the default 600K client. We were running out of memory. */ /* Copyright ©1989, 1990, 1991 Apple Computer, Inc. All rights reserved. */ #ifndef THINK_C #include <Quickdraw.h> #include <Fonts.h> #include <Windows.h> #include <Dialogs.h> #include <Events.h> #include <Memory.h> #include <Menus.h> #include <String.h> #include <Desk.h> #include <Script.h> #include <ToolUtils.h> #define thePort qd.thePort #define screenBits qd.screenBits #endif #include "graphics libraries.h" #include "qd library.h" #include "graphics debugging.h" #include "graphics routines.h" #include "graphics toolbox.h" #include "layout types.h" #include "layout routines.h" #include "layout library.h" #include "layout feature constants.h" /* This macro is useful for constructing fixed values */ #define f(a,b) (((fixed) (a) << 16) + (b)) /* various menu and dialog things */ enum {aboutDLOG = 128, appleMenuID = 128, fileMenuID, editMenuID}; /* resource ID's */ enum {okButton = 1, showsItem, authorItem}; enum { /* Apple Menu */ aboutCommand = 1, /* File Menu */ quitCommand = 1, /* Edit Menu */ undoCommand = 1, cutCommand, copyCommand, pasteCommand, clearCommand}; WindowPtr myWindow, whichWindow; gxViewPort myPort; Rect qdWindowRect; Rect growRect = {40, 40, 32767, 32767}; Rect bigRect = {-32768, -32768, 32767, 32767}; gxRectangle windowRect; MenuHandle appleMenu, fileMenu, editMenu; Boolean done = false; gxColor colorWhite = xRGB (0xFFFF, 0xFFFF, 0xFFFF); /* white */ gxColor hsvInitial = xHSV (0, 0xFFFF, 0xFFFF); /* red */ static void ShowAboutBox () { GrafPtr savePort; DialogPtr theDialog; short itemType; Handle itemHdl; Rect itemRect; short itemHit; GetPort(&savePort); theDialog = GetNewDialog(aboutDLOG, nil, (WindowPtr) -1); SetPort(theDialog); GetDItem(theDialog, authorItem, &itemType, &itemHdl, &itemRect); SetIText(itemHdl, (StringPtr) "\pRice Dream"); GetDItem(theDialog, showsItem, &itemType, &itemHdl, &itemRect); SetIText(itemHdl, (StringPtr) "\pText in a circle"); do { ModalDialog(nil, &itemHit); } while (itemHit != okButton); CloseDialog(theDialog); SetPort(savePort); } static void SetupMenus () { InsertMenu (appleMenu = GetMenu (appleMenuID), 0); AddResMenu (appleMenu, (ResType) 'DRVR'); InsertMenu (fileMenu = GetMenu (fileMenuID), 0); InsertMenu (editMenu = GetMenu (editMenuID), 0); DrawMenuBar (); } static void DoMenuCommand (long mResult) { short theItem = LoWord (mResult), theMenuID = HiWord (mResult); GrafPtr savePort; Str255 daName; switch (theMenuID) { case appleMenuID: if (theItem == aboutCommand) ShowAboutBox (); else { GetItem (appleMenu, theItem, daName); GetPort (&savePort); (void) OpenDeskAcc (daName); SetPort (savePort); } break; case fileMenuID: if (theItem == quitCommand) done = true; break; case editMenuID: break; } HiliteMenu (0); } static short StrLength(char *s) {short len; for (len = 0; *s++ != 0; len++) ; return len; } void main() { EventRecord theEvent; gxDashRecord d; gxColor shapeColor; commonColor kanjiColor = apple_green; gxRectangle bounds, r; gxShape layout, oval, whiteOut, eraseOval, kanji; gxRunControls controls; gxLayoutOptions gxLayoutOptions; char *textRuns[3]; gxStyle textStyles[3]; short textLengths[3], totalLength, level0 = 0; char *text1 = "Aetna "; /* The following is "Arabic Macintosh" in Arabic: */ /* meem, alif, kaf, noon, tah, wau, shin, */ /* <sp>, alif, lam, ein, reh, beh, yeh */ static char text2[] = {0xE5, 0xC7, 0xE3, 0xE6, 0xCA, 0xE8, 0xD4, 0x20, 0xC7, 0xE4, 0xD9, 0xD1, 0xC8, 0xEA, 0}; char *text3 = " Office AWAY."; char *kanjiText = "&"; fixed ascent, descent; gxPoint center; GDHandle max; short mbh = GetMBarHeight (); gxGraphicsClient ourClient; MaxApplZone(); MoreMasters(); MoreMasters(); ourClient = GXNewGraphicsClient(0L, 1024 * 1024, 0L); if (ourClient != NULL) { SetGraphicsLibraryErrors(); SetGraphicsLibraryNotices (); /*GXSetValidation(gxInternalValidation | gxStructureValidation | gxNoMemoryManagerValidation); ** uncomment this for less speed and more error-checking */ InitCommonColors (); InitGraf(&thePort); InitFonts(); InitWindows(); InitMenus (); InitCursor(); SetupMenus (); /* find the deepest monitor, and make a window that just covers it */ max = GetMaxDevice (&bigRect); qdWindowRect = (**max).gdRect; /* bring it down one mbh for the header, maybe another if on main screen */ if (qdWindowRect.top == 0 && qdWindowRect.left == 0) qdWindowRect.top += mbh; qdWindowRect.top += mbh; InsetRect (&qdWindowRect, 4, 4); ShortRectToFixed (&qdWindowRect, &windowRect); center.x = (windowRect.right - windowRect.left) / 2; center.y = (windowRect.bottom - windowRect.top) / 2; myWindow = NewWindow(nil, &qdWindowRect, (StringPtr) "\pCircular Layout Sample", true, documentProc, (WindowPtr) -1L, true, 0L); myPort = GXNewWindowViewPort (myWindow); SetDefaultViewPort (myPort); GXSetViewPortDither( myPort, 4 ); /* When we want to erase the whole window, we just GXDrawShape (whiteOut). */ whiteOut = GXNewShape(gxFullType); GXSetShapeColor (whiteOut, &colorWhite); /* make a 270 x 270 gxRectangle centered in the window */ r.top = center.y - ff(135); r.left = center.x - ff(135); r.bottom = center.y + ff(135); r.right = center.x + ff(135); /* use the gxRectangle to make an oval, and get it ready to be dashed */ oval = NewOval(&r); GXSetShapeFill(oval, gxClosedFrameFill); GXSetShapePen(oval, IntToFixed(14)); shapeColor = hsvInitial; /* gxInitialize the textRuns array */ textRuns[0] = text1; textRuns[1] = text2; textRuns[2] = text3; /* gxInitialize the textLengths array */ textLengths[0] = StrLength(text1); textLengths[1] = StrLength(text2); textLengths[2] = StrLength(text3); totalLength = textLengths[0] + textLengths[1] + textLengths[2]; /* Make a default gxLayoutOptions and gxRunControls */ InitializeLayoutOptions (&gxLayoutOptions); InitializeRunControls (&controls); /* run 0 is 28 pt. Helvetica */ textStyles[0] = NewLayoutStyle((char *) "\pHelvetica", ff(28), 0, &controls, nil, 0, nil); /* run 1 is 28 pt. Baghdad (Arabic) */ textStyles[1] = NewLayoutStyle((char *) "\pBaghdad Plain", ff(28), 0, &controls, nil, 0, nil); /* run 2 is 28 pt. Times Roman */ textStyles[2] = NewLayoutStyle((char *) "\pTimes Roman", ff(28), 0, &controls, nil, 0, nil); kanji = NewSingleLayout ( kanjiText, (char *) "\pTimes Roman", ff(175), &gxLayoutOptions, nil, 0, &controls, nil, 0, nil); GXGetLayoutSpan(kanji, &ascent, &descent); GXGetShapeBounds(kanji, 0, &bounds); GXMoveShapeTo (kanji, center.x - ((bounds.right - bounds.left) / 2), center.y + ((ascent - descent) / 2)); /* make sure that kanji has a unique gxTransform, and scale it */ { gxTransform xform = GXGetShapeTransform(kanji); if (GXGetTransformOwners(xform) > 1) { xform = GXCopyToTransform(nil, xform); GXSetShapeTransform(kanji, xform); GXDisposeTransform (xform); } } GXScaleTransform(GXGetShapeTransform(kanji), IntToFixed(2), f(1,0x6000), center.x, center.y); /* Build the layout. */ layout = GXNewLayout( 3, textLengths, (void *)textRuns, 3, textLengths, textStyles, 1, &totalLength, &level0, &gxLayoutOptions, nil); (void) GXGetShapeBounds (layout, 0, &bounds); GXSetShapeType(layout, gxPathType); /* now use the layout to dash the oval */ d.attributes = gxAutoAdvanceDash | gxBreakDash; d.dash = layout; d.phase = 0; d.advance = bounds.right + ff(10); d.scale = IntToFixed(14); /* make sure that oval has a unique gxTransform, and scale it */ { gxTransform xform = GXGetShapeTransform(oval); if (GXGetTransformOwners(xform) > 1) { xform = GXCopyToTransform(nil, xform); GXSetShapeTransform(oval, xform); GXDisposeTransform (xform); } } GXScaleTransform(GXGetShapeTransform(oval), fixed1*2, f(1,0x6000), center.x, center.y); eraseOval = GXNewShape(gxEmptyType); /* Now just keep re-drawing the gxShape in different colors until it's time to go */ while (!done) { GXSetShapeColor (oval, &shapeColor); GXIgnoreGraphicsNotice( dash_already_set ); GXSetShapeDash (oval, &d); GXPopGraphicsNotice(); GXCacheShape (oval); if (shapeColor.element.hsv.hue == 0) { SetShapeCommonColor (kanji, kanjiColor); GXCacheShape (kanji); if (++kanjiColor > apple_blue) kanjiColor = apple_green; d.phase = 0; } GXDrawShape (eraseOval); GXDrawShape (oval); GXCopyToShape(eraseOval, oval); GXSetShapeColor (eraseOval, &colorWhite); GXDrawShape (kanji); shapeColor.element.hsv.hue += 0x10000/32; d.phase += fract1/32; if (WaitNextEvent(everyEvent, &theEvent, 0, nil)) { switch(theEvent.what) { case mouseDown: switch (FindWindow(theEvent.where, &whichWindow)) { case inSysWindow: SystemClick(&theEvent, whichWindow); break; case inMenuBar: DoMenuCommand (MenuSelect (theEvent.where)); break; case inDrag: DragWindow(whichWindow, theEvent.where, &screenBits.bounds); break; case inGrow: { register long newSize; newSize = GrowWindow(whichWindow, theEvent.where, &growRect); SizeWindow(whichWindow, LoWord(newSize), HiWord(newSize), true); } break; case inGoAway: if (TrackGoAway(whichWindow, theEvent.where)) done = true; break; case inContent: if (whichWindow != FrontWindow()) SelectWindow(whichWindow); break; } break; case keyDown: case autoKey: if (myWindow == FrontWindow () && theEvent.modifiers & cmdKey) DoMenuCommand (MenuKey (theEvent.message & charCodeMask)); break; case updateEvt: BeginUpdate((WindowPtr)theEvent.message); GXDrawShape (whiteOut); GXDrawShape (oval); GXDrawShape (kanji); EndUpdate((WindowPtr)theEvent.message); break; } } } /* dispose everything we've allocated. */ DisposeCommonColors (); GXDisposeShape (oval); GXDisposeShape (eraseOval); GXDisposeShape(layout); GXDisposeShape(kanji); GXDisposeStyle (textStyles[0]); GXDisposeStyle (textStyles[1]); GXDisposeStyle (textStyles[2]); DisposeWindow(myWindow); GXDisposeShape (whiteOut); GXDisposeGraphicsClient(ourClient); } }